package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.foctory.StrategyFactory;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.user.strategy.ItemTypeStrategy;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.joda.time.LocalDateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RabbitService rabbitService;

	@Autowired
	private UserPaidAlbumMapper userPaidAlbumMapper;

	@Autowired
	private UserPaidTrackMapper userPaidTrackMapper;

	@Autowired
	private TrackInfoFeignClient trackInfoFeignClient;

	@Autowired
	private VipServiceConfigMapper vipServiceConfigMapper;

	@Autowired
	private UserVipServiceMapper userVipServiceMapper;

	@Autowired
	private StrategyFactory strategyFactory;
	/**
	 * 微信登录
	 * @param code
	 * @return
	 */
	@Override
	public Map<String, Object> wxLogin(String code) {
		//调用微信的登录api
		WxMaJscode2SessionResult wxMaJscode2SessionResult = null;
		try {
			wxMaJscode2SessionResult  = wxMaService.jsCode2SessionInfo(code);
		} catch (WxErrorException e) {
			throw new RuntimeException(e);
		}
		//openid: 每个人的微信都对应一个微信标识
		String openid = wxMaJscode2SessionResult.getOpenid();
		//利用openid实现登录或注册功能
		UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid));
		//判断对象是否为空
		if (null == userInfo){
			//说明要注册：本质赋值o
			userInfo = new UserInfo();
			userInfo.setWxOpenId(openid);
			userInfo.setNickname("xun:" + System.currentTimeMillis());
			userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
			//保存数据到数据库
			userInfoMapper.insert(userInfo);
			//在此需要给当前注册的用户进行初始化充值；同步： 异步：mq发送消息
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_USER_REGISTER,userInfo.getId());
		}
		//说明要登录：将数据存储到redis，与返回token
		String token = UUID.randomUUID().toString().replaceAll("-","");
		//组成缓存的key
		String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
		//存储数据
		redisTemplate.opsForValue().set(userLoginKey,userInfo,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
		//返回数据
		HashMap<String, Object> map = new HashMap<>();
		map.put("token",token);
		return map;
	}

	/**
	 * 获取用户信息
	 * @param userId
	 * @return
	 */
	@Override
	public UserInfoVo getUserInfo(Long userId) {
		//查询用户信息
		UserInfo userInfo = this.getById(userId);
		//创建一个目标对象
		UserInfoVo userInfoVo = new UserInfoVo();
		//属性拷贝
		BeanUtils.copyProperties(userInfo,userInfoVo);

		return userInfoVo;
	}

	/**
	 * 修改用户信息
	 * @param userId
	 * @param userInfoVo
	 */
	@Override
	public void updateUser(Long userId, UserInfoVo userInfoVo) {
		//创建对象
		UserInfo userInfo = new UserInfo();
		//属性拷贝
		BeanUtils.copyProperties(userInfoVo,userInfo);
		userInfo.setId(userId);
		this.updateById(userInfo);
	}

	@Override
	public Map<Long, Integer> userIsPaidTrack(Long albumId, List<Long> trackIdList, Long userId) {
		//创建map集合,并修改为 为购买买状态
		Map<Long, Integer> map = trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 0));
		//判断是否购买过专辑
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
		if (null != userPaidAlbum){
			//当前用户购买了专辑
			return trackIdList.stream().collect(Collectors.toMap(trackId -> trackId,trackId-> 1));
		}
		//查询用户购买声音的集合列表
		List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getUserId, userId).in(UserPaidTrack::getTrackId, trackIdList));
		//这个列表很可能是空
		if (!CollectionUtils.isEmpty(userPaidTrackList)){
			//购买过的声音
			for (UserPaidTrack userPaidTrack : userPaidTrackList) {
				map.put(userPaidTrack.getTrackId(),1);
			}
		}
		//返回数据
		return map;
	}

	@Override
	public Boolean isPaidAlbum(Long albumId, Long userId) {
		return null != userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId,userId).eq(UserPaidAlbum::getAlbumId,albumId));
	}

	@Override
	public List<Long> findUserPaidTrackList(Long albumId, Long userId) {
		List<Long> userPaidTrackList = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getUserId, userId)
						.eq(UserPaidTrack::getAlbumId, albumId))
				.stream()
				.map(UserPaidTrack::getTrackId)
				.collect(Collectors.toList());
		return userPaidTrackList;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void savePaidRecord(UserPaidRecordVo userPaidRecordVo) {
		//返回策略对象
		ItemTypeStrategy itemTypeStrategy = strategyFactory.getStrategy(userPaidRecordVo.getItemType());
		itemTypeStrategy.savePaidRecord(userPaidRecordVo);
//		//记录用户购买的信息
//		if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(userPaidRecordVo.getItemType())){
//			//购买专辑
//			UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userPaidRecordVo.getUserId())
//					.eq(UserPaidAlbum::getAlbumId, userPaidRecordVo.getItemIdList().get(0)));
//			if (null != userPaidAlbum) {
//				return;
//			}
//			//创建对象保存数据
//			userPaidAlbum = new UserPaidAlbum();
//			//赋值
//			userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
//			userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
//			userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
//			//保存数据
//			userPaidAlbumMapper.insert(userPaidAlbum);
//		}else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(userPaidRecordVo.getItemType())){
//			//声音判断当前购买的声音Id在当前表中是否存在
//			//用户购买的声音列表
//			List<Long> itemIdList = userPaidRecordVo.getItemIdList();
//			//查询用户已购买的声音列表
//			LambdaQueryWrapper<UserPaidTrack> wrapper = new LambdaQueryWrapper<>();
//			wrapper.in(UserPaidTrack::getTrackId,itemIdList)
//					.eq(UserPaidTrack::getUserId,userPaidRecordVo.getUserId());
//			//用户在已购买的类表中买了对应的声音
//			List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(wrapper);
//			//需要把这个集合编程set集合，判断是否存在
//			List<Long> paidTrackIdSet = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
//			//判断
//			if (!CollectionUtils.isEmpty(userPaidTrackList)){
//				//有买过
//				for (Long itemId : itemIdList) {
//					//是否包含
//					if (paidTrackIdSet.contains(itemId)){
//						//需要将包含的声音添加到集合中，用来记录哪些声音属于购买过
//						//需要用Mq增加余额
//						continue;
//					}
//				}
//			}
//			//根据声音获取声音对象
//			Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0));
//			Assert.notNull(trackInfoResult,"查询声音信息失败");
//			TrackInfo trackInfo = trackInfoResult.getData();
//			Assert.notNull(trackInfoResult,"查询声音失败");
//			//没有买过
//			for (Long trackId : itemIdList) {
//				//创建对象
//				UserPaidTrack userPaidTrack = new UserPaidTrack();
//				userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
//				userPaidTrack.setUserId(userPaidRecordVo.getUserId());
//				userPaidTrack.setAlbumId(trackInfo.getAlbumId());
//				userPaidTrack.setTrackId(trackId);
//				//保存数据
//				userPaidTrackMapper.insert(userPaidTrack);
//			}
//		}else {
//			//购买Vip可能需要续期
//			///获取购买的时长
//			Long vipServiceId = userPaidRecordVo.getItemIdList().get(0);
//			VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(vipServiceId);
//			Integer serviceMonth = vipServiceConfig.getServiceMonth();
//			//保存数据
//			UserVipService userVipService = new UserVipService();
//			//赋值
//			userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
//			userVipService.setUserId(userPaidRecordVo.getUserId());
//			Date currenTime = new Date();
//			userVipService.setStartTime(currenTime);
//			//过期时间：稍后完成；第一种情况：第一次购买；第二种情况：续期
//			//判断当前用户是否是vip并且未过期；续期；
//			UserInfo userInfo = userInfoMapper.selectById(userPaidRecordVo.getUserId());
//			if (userInfo.getIsVip() == 1 && userInfo.getVipExpireTime().after(currenTime)){
//				//属于续期
//				//  LocalDateTime localDateTime = new LocalDateTime(userInfo.getVipExpireTime());
//				//                Date expireTime = localDateTime.plusMonths(serviceMonth).toDate();
//				//                System.out.println("过期时间：" + expireTime);
//				//                userVipService.setExpireTime(expireTime);
//				currenTime = userInfo.getVipExpireTime();
//			}
//			//            else {
//			//                //  第一次购买的vip的过期时间;;
//			//                //  userVipService.setExpireTime(new LocalDateTime(new Date()).plusMonths(serviceMonth).toDate());
//			//            }
//			//  创建对象
//			LocalDateTime localDateTime = new LocalDateTime(currenTime);
//			//获取过期时间
//			Date expireTime = localDateTime.plusMonths(serviceMonth).toDate();
//			//获取过期时间
//			userVipService.setExpireTime(expireTime);
//			//保存Vip购买记录
//			userVipServiceMapper.insert(userVipService);
//			//修改用户的vip标识
//			userInfo.setIsVip(1);
//			userInfo.setVipExpireTime(expireTime);
//			this.updateById(userInfo);
//		}
	}
}
